package com.chenyue.cm.api.account;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.chenyue.cm.account.domain.JdBankCardUser;
import com.chenyue.cm.account.domain.JdWithdrawApply;
import com.chenyue.cm.account.service.JdAccountService;
import com.chenyue.cm.account.service.JdBankCardUserService;
import com.chenyue.cm.account.service.JdWithdrawApplyService;
import com.chenyue.cm.account.vo.AccountSource;
import com.chenyue.cm.auth.Login;
import com.chenyue.cm.auth.LoginUser;
import com.chenyue.cm.bean.Success;
import com.chenyue.cm.common.constant.ConstantValues;
import com.chenyue.cm.common.constant.ErrorCode;
import com.chenyue.cm.common.domain.JdConstantValues;
import com.chenyue.cm.common.service.JdConstantValuesService;
import com.chenyue.cm.common.utils.StringUtil;
import com.chenyue.cm.common.utils.StringUtils;
import com.chenyue.cm.common.vo.Page;
import com.chenyue.cm.user.domain.JdAppUser;
import com.chenyue.cm.user.service.JdAppUserService;
import com.chenyue.cm.utils.DateUtils;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.List;

/**
 * @author libingxing
 */
@Api(tags = "银行卡模块")
@RestController
@RequestMapping("/api/bank")
public class ApiBankController {

    private final JdBankCardUserService bankCardUserService;

    private final JdWithdrawApplyService withdrawApplyService;

    private final JdAppUserService appUserService;

    private final JdAccountService accountService;

    private final JdConstantValuesService constantValuesService;

    public ApiBankController(JdBankCardUserService bankCardUserService, JdWithdrawApplyService withdrawApplyService, JdAppUserService appUserService, JdAccountService accountService, JdConstantValuesService constantValuesService) {
        this.bankCardUserService = bankCardUserService;
        this.withdrawApplyService = withdrawApplyService;
        this.appUserService = appUserService;
        this.accountService = accountService;
        this.constantValuesService = constantValuesService;
    }

    @Login
    @GetMapping("getBankCard")
    @ApiOperation("获取用户已绑定的银行卡")
    @ApiOperationSupport(order = 1)
    public Success<List<JdBankCardUser>> getBankCard(
            @ApiIgnore @LoginUser JdAppUser user
    ) {
        final List<JdBankCardUser> list = bankCardUserService.lambdaQuery().eq(JdBankCardUser::getUserId, user.getId()).list();
        for (JdBankCardUser cardUser : list) {
            String cardNumber = cardUser.getCardNumber();
            final String cardNumberNew = StringUtil.convertStr(cardNumber, cardNumber.length() - 8, 4, cardNumber.length() - 4);
            cardUser.setCardNumber(cardNumberNew);
        }
        return Success.success(list);
    }

    @Login
    @PostMapping("/bindCard")
    @ApiOperation("绑定银行卡")
    @ApiOperationSupport(order = 2)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "银行卡号", name = "cardNumber", dataType = "string", required = true),
            @ApiImplicitParam(value = "开户行", name = "bankName", dataType = "string", required = true),
            @ApiImplicitParam(value = "银行预留手机号", name = "mobile", dataType = "string", required = true),
            @ApiImplicitParam(value = "验证码", name = "verifyCode", dataType = "string", required = true),
            @ApiImplicitParam(value = "持卡人姓名", name = "name", dataType = "string", required = true)
    })
    public Success<String> bindCard(
            @ApiIgnore @LoginUser JdAppUser user,
            String cardNumber, String verifyCode, String bankName, String mobile, String name
    ) {
        final String errorMsg = appUserService.checkVerifyCode(mobile, verifyCode);
        if (StringUtils.isNotBlank(errorMsg)) {
            return Success.error(errorMsg);
        }
        Wrapper<JdBankCardUser> wrapper = new QueryWrapper<JdBankCardUser>().lambda()
                .eq(JdBankCardUser::getCardNumber, cardNumber).last(" limit 1");
        final JdBankCardUser one = bankCardUserService.getOne(wrapper);
        if (one != null) {
            if (one.getUserId().equals(user.getId())) {
                return Success.error("您已绑定该卡");
            } else {
                return Success.error("该银行卡已被绑定");
            }
        }
        JdBankCardUser bankCardUser = new JdBankCardUser();
        bankCardUser.setBankName(bankName);
        bankCardUser.setUserId(Integer.valueOf(user.getId()));
        bankCardUser.setCardNumber(cardNumber);
        bankCardUser.setMobile(mobile);
        bankCardUser.setName(name);
        final boolean save = bankCardUserService.save(bankCardUser);
        return save ? Success.success() : Success.error(ErrorCode.INSERT_ERROR.getMsg());
    }

    @Login
    @PostMapping("/withdraw")
    @ApiOperation("提现申请")
    @ApiOperationSupport(order = 3)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "提现金额", name = "amount", dataType = "double", required = true),
            @ApiImplicitParam(value = "银行卡id", name = "cardId", dataType = "integer", required = true)
    })
    public Success<String> withdraw(
            @ApiIgnore @LoginUser JdAppUser user,
            Double amount, Integer cardId
    ) {
        Double ableAmount = accountService.getWithdrawAbleAmount(Integer.valueOf(user.getId()));
        if (ableAmount < amount) {
            return Success.error("可提现额度不足");
        }
        JdWithdrawApply apply = new JdWithdrawApply();
        apply.setUserId(Integer.valueOf(user.getId()));
        apply.setCardId(cardId);
        apply.setAmount(amount);
        apply.setCreateTime(DateUtils.getToday());
        final boolean save = withdrawApplyService.save(apply);
        final JdConstantValues one = constantValuesService.lambdaQuery().eq(JdConstantValues::getConstantKey, ConstantValues.EXCHANGE_RATE).one();
        double exchangeRate = 0D;
        if (one != null) {
            exchangeRate = Double.parseDouble(one.getConstantValue());
        }
        accountService.costume(Integer.valueOf(user.getId()), amount * exchangeRate, AccountSource.WITHDRAW, apply.getId());
        return save ? Success.success() : Success.error(ErrorCode.INSERT_ERROR.getMsg());
    }

    @Login
    @GetMapping("/withdrawRecord")
    @ApiOperation("提现记录")
    @ApiOperationSupport(order = 1)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "页数", name = "page", dataType = "string", required = true),
            @ApiImplicitParam(value = "条数", name = "rows", dataType = "string", required = true),
    })
    public Success<Page<List<JdWithdrawApply>>> withdrawRecord(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer rows,
            @ApiIgnore @LoginUser JdAppUser user
    ) {
        final LambdaQueryChainWrapper<JdWithdrawApply> eq = withdrawApplyService.lambdaQuery()
                .eq(JdWithdrawApply::getUserId, user.getId());
        final Integer total = eq.count();
        Page<List<JdWithdrawApply>> result = new Page<>(page, rows, total);
        final List<JdWithdrawApply> list = eq
                .last(result.convertPage())
                .list();
        result.setContent(list);
        return Success.success();
    }

}
